package com.speechb.controller;


import com.github.pagehelper.PageHelper;
import com.ld.lucenex.base.Page;
import com.ld.lucenex.service.ServiceFactory;
import com.ld.lucenex.service.ServiceImpl;
import com.speechb.common.text.PageUtil;
import com.speechb.common.text.TextUtil;
import com.speechb.controller.base.BaseController;
import com.speechb.entity.Blog;
import com.speechb.manager.ThreadPoolManager;
import com.speechb.modules.system.web.annotation.AuthLogin;
import com.speechb.modules.system.web.annotation.CheckParam;
import com.speechb.service.IBlogService;
import com.speechb.service.IMenuService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.index.Term;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.util.List;

/**
 * <p>
 * 博客 前端控制器
 * </p>
 *
 * @author llj
 * @since 2021-03-14
 */
@Controller
@RequestMapping("")
public class BlogController extends BaseController {
    private static final Logger LOGGER = LoggerFactory.getLogger(BlogController.class);

    @Autowired
    IBlogService blogService;

    @Autowired
    IMenuService menuService;

    private static final int PAGE_SIZE = 12;

    @PostMapping("/blog/publish")
    @ResponseBody
    @AuthLogin
    public void publish() {
        Blog blog = new Blog();
        Integer status = getInt("status");
        blog.setHtml_content(getPara("html_content"));
        blog.setTag(getPara("tag"));
        blog.setMarkdown_content(getPara("markdown_content"));
        blog.setType_id(getInt("type_id"));
        blog.setTitle(getPara("title"));
        blog.setId(TextUtil.getUUID());
        blog.setUid(getUid());
        blog.setStatus(status);
        blog.setSummary(TextUtil.getSummary(blog.getHtml_content(), 150));
        boolean save = false;//blogService.save(blog);
        ServiceImpl<Blog> basisService = ServiceFactory.getService(ServiceImpl.class);
        List<Blog> luceneData = blogService.findLuceneData(blog.getId());
        try {
            basisService.addObjects(luceneData);
        } catch (IOException e) {
            LOGGER.warn("添加索引失败", e);
        }
        if (save) {
            renderUnCompressSuccess();
            return;
        }
        renderFail();
    }

    @PutMapping("/blog/update")
    @ResponseBody
    @AuthLogin
    public void update() {
        String id = getPara("id");
        Blog dbBlog = blogService.findById(id);
        if (dbBlog == null) {
            renderNotExist();
            return;
        }
        Integer status = getInt("status");
        Blog blog = new Blog();
        blog.setHtml_content(getPara("html_content"));
        blog.setTag(getPara("tag"));
        blog.setMarkdown_content(getPara("markdown_content"));
        blog.setType_id(getInt("type_id"));
        blog.setTitle(getPara("title"));
        blog.setId(id);
        blog.setUid(getUid());
        blog.setStatus(status);
        blog.setSummary(TextUtil.getSummary(blog.getHtml_content(), 150));
        ///boolean update = blogService.updateById(blog);
        ServiceImpl<Blog> basisService = ServiceFactory.getService(ServiceImpl.class);
        try {
            basisService.deleteDocuments(new Term("id", blog.getId()));

            List<Blog> luceneData = blogService.findLuceneData(blog.getId());
            basisService.addObjects(luceneData);
        } catch (IOException e) {
            LOGGER.warn("删除索引失败", e);
        }

        renderFail();
    }

    @GetMapping(value = "/detail/{id}")
    public String articleContent(@PathVariable String id, Model model) {
        Blog blog = blogService.findContent(id);
        if (blog == null) {
            setStatus(404);
            return "web/app/error/404";
        }

        if (blog.getStatus() == 0) {
            if (!org.apache.commons.lang3.StringUtils.equals(getUid(), blog.getUid())) {
                setStatus(403);
                return "web/app/error/403";
            }
        }
        boolean isMk = StringUtils.isNotEmpty(blog.getMarkdown_content());
        if (isMk) {
            blog.setMarkdown_content(TextUtil.convertArticleContent(blog.getMarkdown_content()));
        } else {
            blog.setHtml_content(TextUtil.convertArticleContent(blog.getHtml_content()));
        }
        if (StringUtils.equals(getUid(), blog.getUid())) {
            // 显示编辑按钮
            blog.setCanEdit(true);
        }
        model.addAttribute("blog", blog);
        addHot(id, 1);
        if (isMk) {
            return "web/app/mk_content";
        }
        return "web/app/article_content";
    }

    @GetMapping("/blog/update_info")
    @ResponseBody
    @AuthLogin
    public void updateInfo() {
        String id = getPara("id");
        Blog blog = blogService.findById(id);
        if (blog == null) {
            renderNotExist();
            return;
        }
        if (!StringUtils.equals(blog.getUid(), getUid())) {
            renderNoPermission();
            return;
        }
        setData(blog);
        renderUnCompressSuccess();
    }

    private void addHot(String id, int hot) {
        ThreadPoolManager.newInstance().addExecuteTask(() -> blogService.updateScanCount(id,hot));
    }

    @RequestMapping("/search")
    @CheckParam({"keyword"})
    public ModelAndView search() {
        String keyword = getPara("keyword");
        // 当页码参数和页数量大小未上传时设置默认值。
        int roleType = 2;
        return getModelAndView(keyword, roleType, getPageNum());
    }

    private ModelAndView getModelAndView(String keyword, int roleType, int pageNum) {
        List<Blog> blogList = null;
        int count = 0;
        Page<Blog> page = blogService.search(keyword, roleType, pageNum, PAGE_SIZE, getUid());
        if (page != null) {
            count = page.getTotalPage();
            blogList = page.getList();
        }
        if (CollectionUtils.isNotEmpty(blogList)) {
            blogList.forEach(blog -> {
                if (blog.getHtml_content() != null) {
                    int maxLength = 200;
                    if (blog.getHtml_content().length() < maxLength) {
                        maxLength = blog.getHtml_content().length();
                    }
                    blog.setSummary(blog.getHtml_content().substring(0, maxLength));
                }
            });
        }
        blogService.convertConverUrl(blogList);
        ModelAndView mav = new ModelAndView("web/app/index");
        mav.addObject("index", PageUtil.getPageInd(pageNum, keyword, count, "/search/"));
        mav.addObject("list", blogList);
        mav.addObject("keyword", keyword);
        mav.addObject("menus", menuService.menulist());
        return mav;
    }

    @GetMapping("/search/{keyword}/{pageNum}")
    public ModelAndView webSearch(@PathVariable String keyword, @PathVariable int pageNum) {
        if (StringUtils.isEmpty(keyword)) {
            keyword = getPara("keyword");
        }
        int roleType = 2;
        // 没有页码重置为1
        pageNum = pageNum == 0 ? 1 : pageNum;
        return getModelAndView(keyword, roleType, pageNum);
    }

    @GetMapping("/owner")
    @AuthLogin
    public ModelAndView owner() {
        String status = getPara("status");
        com.github.pagehelper.Page pageHelper = PageHelper.startPage(1, PAGE_SIZE, true);
        List<Blog> blogList = blogService.findByUser(getUid(), status == null ? null : Integer.parseInt(status));
        int pageNum = getPageNum();
        blogService.convertConverUrl(blogList);
        ModelAndView mav = new ModelAndView("web/app/index");
        mav.addObject("index", PageUtil.getPageInd(pageNum, status, pageHelper.getPages(), "/owner/"));
        mav.addObject("list", blogList);
        return mav;
    }

    @GetMapping("/owner/{status}/{pageNum}")
    @AuthLogin
    public ModelAndView owner(@PathVariable Integer status, @PathVariable int pageNum) {
        com.github.pagehelper.Page pageHelper = PageHelper.startPage(pageNum, PAGE_SIZE, true);
        List<Blog> blogList = blogService.findByUser(getUid(), status);
        blogService.convertConverUrl(blogList);
        ModelAndView mav = new ModelAndView("web/app/index");
        mav.addObject("index", PageUtil.getPageInd(pageNum, status, pageHelper.getPages(), "/owner/"));
        mav.addObject("list", blogList);
        return mav;
    }

    @GetMapping("/owner/{pageNum}")
    @AuthLogin
    public ModelAndView owner(@PathVariable int pageNum) {
        com.github.pagehelper.Page pageHelper = PageHelper.startPage(pageNum, PAGE_SIZE, true);
        List<Blog> blogList = blogService.findByUser(getUid(), null);
        blogService.convertConverUrl(blogList);
        ModelAndView mav = new ModelAndView("web/app/index");
        mav.addObject("index", PageUtil.getPageInd(pageNum, null, pageHelper.getPages(), "/owner/"));
        mav.addObject("list", blogList);
        return mav;
    }
}
